using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PlayerCtrl : MonoBehaviour {
	
	// Wood Collided
	private RaycastHit hit;
	//drift value - for Item Drift
	private static float g_translateValue;
	public static float TranslateValue{
		get{return g_translateValue;}
	}
	
	private static MoveState g_moveState;
	public static MoveState g_MoveState{get{return g_moveState;}}
	

	
	//param
	private static float g_moveSpd = 12;// Player Move Speed
	public static float g_MoveSpd{get{return g_moveSpd;}
								  set{g_moveSpd = value;}}
	private static float g_Gravity = 10;
	
	private CharacterController m_cctrl;
	
	private const float m_collidedT = .6f;
	private float m_collidedT_Apply,m_collidedMin,m_collidedMax;
	
	//Rotate Device Angle
	private static float g_angle,g_bufferAngle;
	public static float g_Angle{get{return g_angle;}}
	
	private static float g_rotTime;
	public static float g_RotTime{get{return Time.timeSinceLevelLoad-g_rotTime;}}
	
	private Wood m_wood;//wood where player stand on
	
	//State Operation
	private static OperationState g_operationState;
	public static OperationState g_OperationState{get{return g_operationState;}}
	public static void SwitchOperationState(){
		//@DO : Switch Between Walk / Rotate Device
		g_operationState = (OperationState)(((int)g_operationState+1)%2);
		Idle();//!!Important!! for DeBug
		
	}
	
	void Awake(){
		
		Resources.UnloadUnusedAssets();
		g_rotTime = 0;
		m_cctrl = GetComponent<CharacterController>();
		g_moveState = MoveState.None;
		m_collidedT_Apply = m_collidedT * transform.localScale.y;
		m_collidedMin = transform.localScale.x/2;
		m_collidedMax = transform.localScale.x;
		//Initial Should be Walk State
		g_operationState = OperationState.Walk;
	}
	
	void Update(){
		//Prop translate Value
		g_translateValue = Mathf.Sin(Time.timeSinceLevelLoad*5)*Time.deltaTime/5;
		
		#if UNITY_ANDROID
		////begin calc Rot Device - Smooth Rotate
		g_bufferAngle = (Input.acceleration.y*-90)/90*90;
		
		if(Mathf.Abs(g_bufferAngle-g_angle)>2.5f){
			g_rotTime = Time.timeSinceLevelLoad;
			g_angle = g_bufferAngle;
		}
		
		//g_oldAngle = g_bufferAngle;
		////end
		
		if(g_operationState == OperationState.Walk){
		
			if(Input.acceleration.y>.2f){
				MoveLeft();
			}else if(Input.acceleration.y<-.2f){
				MoveRight();
			}else {
				Idle();
			}
			
		}
		
		#endif

#if UNITY_EDITOR

		if(g_operationState == OperationState.Walk){
			if(Input.GetKey(KeyCode.LeftArrow)){
				MoveLeft();
			}
			else if(Input.GetKey(KeyCode.RightArrow)){
				MoveRight();
			}
			if(Input.GetKeyUp(KeyCode.LeftArrow)){
				Idle();
			}
			else if(Input.GetKeyUp(KeyCode.RightArrow)){
				Idle();
			}
		}
		
#endif
		
		
		if(m_cctrl.isGrounded){
			switch(g_moveState){
			case MoveState.None:
				
				break;
			case MoveState.Left:
				if(CanMoveLeft()){
					m_cctrl.Move(-transform.right*g_moveSpd*Time.deltaTime);
				}
				break;
			case MoveState.Right:
				if(CanMoveRight()){
					m_cctrl.Move(transform.right*g_moveSpd*Time.deltaTime);					
				}
				break;
			}
		}else {
			m_cctrl.Move(-transform.up*g_Gravity*Time.deltaTime);
		}
		if(Input.GetKey(KeyCode.Escape)){
			
			Application.Quit();
			
		}
		
	}
	private static void MoveLeft(){
		if(g_moveState != MoveState.Left){
			g_moveState = MoveState.Left;
		}
	}
	private static void MoveRight(){
		if(g_moveState != MoveState.Right){
			g_moveState = MoveState.Right;
		}
	}
	private static void Idle(){
		if(g_moveState != MoveState.None)
			g_moveState = MoveState.None;
	}
	//Function determin can move to left side
	private bool CanMoveLeft(){
		bool canMove = false;	
		
		if(Physics.Raycast(new Ray(transform.position+transform.up-transform.right*m_collidedT_Apply,-transform.up),out hit)){
			if(hit.transform.CompareTag("wood")){
				if(hit.distance>m_collidedMin && hit.distance<m_collidedMax){
					if(m_wood != hit.transform.GetComponent<Wood>()){
						if(m_wood != null){
							
							m_wood.LeaveWood();
							
						}
						if((m_wood = hit.transform.GetComponent<Wood>()) != null){
							m_wood.EnterWood();
						}
					}
					
					transform.rotation = Quaternion.Euler(transform.rotation.x,0,hit.transform.eulerAngles.z);
					canMove = true;
					
				}else return false;
			}
			else return false;			
		}
		return canMove;
	}
	//Function determin can move to right side
	private bool CanMoveRight(){
		bool canMove = false;
		
		if(Physics.Raycast(new Ray(transform.position+transform.up+transform.right*m_collidedT_Apply,-transform.up),out hit)){
			if(hit.transform.CompareTag("wood")){
				if(hit.distance>m_collidedMin && hit.distance<m_collidedMax){
					
					if(m_wood != hit.transform.GetComponent<Wood>()){
						if(m_wood != null){
							
							m_wood.LeaveWood();
							
						}
						if((m_wood = hit.transform.GetComponent<Wood>()) != null){
							m_wood.EnterWood();
						}
					}
					transform.rotation = Quaternion.Euler(transform.rotation.x,0,hit.transform.eulerAngles.z);
					canMove = true;
					}else return false;
				}
			else return false;	
		}
		
		return canMove;
	}
}
public enum MoveState{	
	Left = 1,
	Right = 2,
	None = 3
}
public enum OperationState{
	Walk,
	RotateDev
}